package com.csx.base.concurrency.completableFuture;

import com.csx.base.concurrency.util.TimeUtil;

import java.util.concurrent.*;
import java.util.function.*;

/**
 * <p> what does this class do ? </p>
 * <p> How does it work ?</p>
 * <p> Why does it do this ?</p>
 *
 * @author cuisongxu
 * @date 2024/12/5 周四 9:03
 */
public class CompletableFutureTest {
    
    private final ExecutorService executor = new ThreadPoolExecutor(
            5,
            10,
            300,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(100),
            new ThreadPoolExecutor.AbortPolicy());

    /**
     * 一. 创建异步任务
     *
     * <p>1.1 根据 Supplier 创建 CompletableFuture 任务
     *
     * <pre> {@code
     *
     *  //使用内置线程ForkJoinPool.commonPool()，根据supplier构建执行任务
     *  public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
     *
     *  //指定自定义线程，根据supplier构建执行任务
     *  public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
     * }
     * </pre>
     *
     * <p> 1.2 根据 Runnable 创建 CompletableFuture 任务
     * <pre>{@code
     *
     *   //使用内置线程ForkJoinPool.commonPool()，根据runnable构建执行任务
     *   public static CompletableFuture<Void> runAsync(Runnable runnable)
     *
     *   //指定自定义线程，根据runnable构建执行任务
     *   public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
     * }
     * </pre>
     *
     * <p> 1.3 常量值作为 CompletableFuture 任务返回
     * <pre>{@code
     *
     *   //有时候是需要构建一个常量的CompletableFuture
     *   public static <U> CompletableFuture<U> completedFuture(U value)
     *
     * }
     * </pre>
     */
    public void testCreateCompletableFuture() {
        
        // 1.1. 根据 Supplier 创建 CompletableFuture 任务
        CompletableFuture<String> supplierFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("使用 supplyAsync() 创建 CompletableFuture");
            return "使用 supplyAsync() 创建出的 CompletableFuture 对象";
        },executor);
        
        // 1.2 根据 Runnable 创建 CompletableFuture 任务
        CompletableFuture<Void> runnableFuture = CompletableFuture.runAsync(() -> {
            System.out.println("使用 runAsync() 创建出的 CompletableFuture");
        },executor);
        
        // 1.3 常量值作为 CompletableFuture 返回
        CompletableFuture<String> constantFuture = CompletableFuture.completedFuture("使用 completedFuture() 创建出的 CompletableFuture");


        // 阻塞等待三个 CompletableFuture 执行完毕
        String supplierRes = supplierFuture.join();
        runnableFuture.join();
        String constantRes = constantFuture.join();

        System.out.println("supplierRes: " + supplierRes);
        System.out.println("constantRes: " + constantRes);
    }


    /**
     * 二、 CompletableFuture 线程串行执行
     * <p> 2.1 任务完成则运行 action, 不依赖上一个任务的结果,无返回值
     * <pre>{@code
     *   public CompletableFuture<Void> thenRun(Runnable action)
     *   public CompletableFuture<Void> thenRunAsync(Runnable action)
     *   //action用指定线程池执行
     *   public CompletableFuture<Void> thenRunAsync(Runnable action, Executor executor)
     * }
     * </pre>
     *
     * <p> 2.2 任务完成则运行 action, 依赖上一个任务的结果,无返回值
     * <pre>{@code
     *   public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
     *   public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action)
     *   //action用指定线程池执行
     *   public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor)
     * }
     * </pre>
     *
     * <p> 2.3 任务完成则运行 fn, 依赖上一个任务的结果,有返回值
     * <pre>{@code
     *   public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
     *   public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn)
     *   //fn用指定线程池执行
     *   public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
     * }
     * </pre>
     *
     * <p> 2.4 任务完成则运行 fn, 依赖上一个任务的结果,有返回值,与2.3的区别在于返回的是 CompletionStage, 2.3返回的是 U
     * <pre>{@code
     *   public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
     *   public <U> CompletableFuture<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn)
     *   //fn用指定线程池执行
     *   public <U> CompletableFuture<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn,
     * 		Executor executor)
     * }
     * </pre>
     */
    public void testCompletableFutureSerialExecute() {

        // 2.1 任务完成则运行 runnable,不依赖上个任务的执行结果,无返回值
        Runnable runnable = () -> System.out.println("执行 thenRunAsync(),不依赖上个任务的结果,无返回值");
        CompletableFuture<Void> thenRunFuture = CompletableFuture
                .supplyAsync(() -> "hello thenRunAsync")
                .thenRunAsync(runnable, executor);


        // 2.2 任务完成则运行 consumer,依赖上个任务的执行结果,无返回值
        Consumer<String> consumer = (data) -> System.out.println("执行 thenAcceptAsync(),依赖上个任务的结果: [ " + data + " ],无返回值");
        CompletableFuture<Void> thenAcceptFuture = CompletableFuture
                .supplyAsync(() -> "hello thenAccept")
                .thenAcceptAsync(consumer, executor);

        // 2.3 任务完成则运行 function,依赖上个任务的执行结果,有返回值
        Function<String,String> function = (data) -> {
            System.out.println("执行 thenApplyAsync(),依赖上个任务的结果: [ " + data + " ],有返回值");
            return "thenApplyAsync() 执行结果";
        };
        CompletableFuture<String> thenApplyFuture = CompletableFuture
                .supplyAsync(() -> "hello thenApply")
                .thenApplyAsync(function, executor);


        // 2.4 任务完成则运行 function2,依赖上个任务的执行结果,有返回值(返回值为CompletionStage)
        CompletableFuture<String> f = CompletableFuture.completedFuture("thenCompose result");
        Function<String, CompletionStage<String>> function2 = (data) -> {
            System.out.println("执行 thenComposeAsync(),依赖上个任务的结果: [ " + data + " ],有返回值(返回值为CompletionStage)");
            return f;
        };
        CompletableFuture<String> thenComposeFuture = CompletableFuture
                .supplyAsync(() -> "hello thenCompose")
                .thenComposeAsync(function2, executor);


        // 阻塞等待所有 future 运行完毕
        thenRunFuture.join();
        thenAcceptFuture.join();
        String thenApplyFutureRes = thenApplyFuture.join();
        String thenComposeFutureRes = thenComposeFuture.join();

        System.out.println("thenApplyFutureRes: " + thenApplyFutureRes);
        System.out.println("thenComposeFutureRes: " + thenComposeFutureRes);

    }


    /**
     * 三、 CompletableFuture 线程并行执行
     * <p> 3.1 两个 CompletableFuture 并行执行完,然后执行 runnable,不依赖上两个任务的结果,无返回值
     * <pre>{@code
     *   public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other, Runnable action)
     *   public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action)
     *   public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor)
     * }
     * </pre>
     *
     * <p> 3.2 两个 CompletableFuture 并行执行完,然后执行 consumer,依赖上两个任务的结果,无返回值
     * <pre>{@code
     *   //调用方任务和other并行完成后执行action，action再依赖消费两个任务的结果，无返回值
     *   public <U> CompletableFuture<Void> thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)
     *   //两个任务异步完成，fn再依赖消费两个任务的结果，无返回值，使用默认线程池
     *   public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)
     *   //两个任务异步完成，fn（用指定线程池执行）再依赖消费两个任务的结果，无返回值
     *   public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor)
     * }
     * </pre>
     *
     * <p> 3.3 两个 CompletableFuture 并行执行完,然后执行 function,依赖上两个任务的结果,有返回值
     * <pre>{@code
     *   //调用方任务和other并行完成后，执行fn，fn再依赖消费两个任务的结果，有返回值
     *   public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
     *   //两个任务异步完成，fn再依赖消费两个任务的结果，有返回值，使用默认线程池
     *   public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
     *   //两个任务异步完成，fn（用指定线程池执行）再依赖消费两个任务的结果，有返回值
     *   public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor)
     * }
     * </pre>
     */
    public void testCompletableFutureParallelANDExecute() {

        CompletableFuture<String> firstFuture = getOneCompletableFuture("firstFuture",2);

        // 3.1 两个 CompletableFuture 并行执行完,然后执行 runnable,不依赖上两个任务的结果,无返回值
        Runnable runnable = getOneRunnable("runAfterBothAsync()");
        CompletableFuture<Void> runAfterBothFuture = CompletableFuture
                // 这就是第二个CompletableFuture任务
                .supplyAsync(getOneSupplier("runAfterBothAsync()"), executor)
                .runAfterBothAsync(firstFuture, runnable, executor);

        try {
            TimeUnit.SECONDS.sleep(10);
            System.out.println();
            System.out.println();
            System.out.println();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }



        // 3.2 两个 CompletableFuture 并行执行完,然后执行 consumer,依赖上两个任务的结果,无返回值
        BiConsumer<String, String> consumer = getOneBiConsumer("thenAcceptBothAsync()");
        CompletableFuture<Void> thenAcceptBothFuture = CompletableFuture
                .supplyAsync(getOneSupplier("thenAcceptBothAsync()"), executor)
                .thenAcceptBothAsync(firstFuture, consumer, executor);

        try {
            TimeUnit.SECONDS.sleep(10);
            System.out.println();
            System.out.println();
            System.out.println();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }



        // 3.3 两个 CompletableFuture 并行执行完,然后执行 function,依赖上两个任务的结果,有返回值
        BiFunction<String,String,String> function = getOneBiFunction("thenCombineAsync()");
        CompletableFuture<String> thenCombineFuture = CompletableFuture
                .supplyAsync(getOneSupplier("thenCombineAsync()"), executor)
                .thenCombineAsync(firstFuture, function, executor);


        // 阻塞等待三个 future 执行完毕
        runAfterBothFuture.join();
        thenAcceptBothFuture.join();
        String thenCombineFutureRes = thenCombineFuture.join();
        System.out.println("thenCombineFutureRes: " + thenCombineFutureRes);

    }

    /**
     * 四、 CompletableFuture 线程并行运行,任意一个执行完都触发下一个任务的执行
     * <p> 4.1 两个任务任意一个运行完毕,运行 action,不依赖任务的返回结果,无返回值
     * <pre>{@code
     *   public CompletableFuture<Void> runAfterEither(CompletionStage<?> other, Runnable action)
     *   public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other, Runnable action)
     *   //action用指定线程池执行
     *   public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,Runnable action, Executor executor)
     * }
     * </pre>
     *
     * <p> 4.2 两个任务任意一个运行完毕,运行 action,依赖任务的返回结果,无返回值
     * <pre>{@code
     *   public CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action)
     *   public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other,Consumer<? super T> action, Executor executor)
     *   //action用指定线程池执行
     *   public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other,Consumer<? super T> action, Executor executor)
     * }
     * </pre>
     *
     * <p> 4.3 两个任务任意一个运行完毕,运行 fn,依赖任务的返回结果,有返回值
     * <pre>{@code
     *   public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other,Function<? super T, U> fn)
     *   public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other,Function<? super T, U> fn)
     *   //fn用指定线程池执行
     *   public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other,Function<? super T, U> fn, Executor executor)
     * }
     * </pre>
     */
    public void testCompletableFutureParallelORExecute() {

        CompletableFuture<String> firstFuture = getOneCompletableFuture("firstFuture",2);
        // 4.1 两个任务任意一个运行完毕,运行 action,不依赖任务的返回结果,无返回值
        CompletableFuture<Void> runAfterEitherFuture = CompletableFuture
                .supplyAsync(getOneSupplier("runAfterEitherAsync()"), executor)
                .runAfterEitherAsync(firstFuture, getOneRunnable("runAfterEitherAsync()"), executor);

        try {
            TimeUnit.SECONDS.sleep(10);
            System.out.println();
            System.out.println();
            System.out.println();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }


        // 4.2 两个任务任意一个运行完毕,运行 action,依赖任务的返回结果,无返回值
        firstFuture = getOneCompletableFuture("firstFuture",2);
        CompletableFuture<Void> acceptEitherFuture = CompletableFuture
                .supplyAsync(getOneSupplier("acceptEitherAsync()"), executor)
                .acceptEitherAsync(firstFuture, getOneConsumer("acceptEitherAsync()"), executor);
        try {
            TimeUnit.SECONDS.sleep(10);
            System.out.println();
            System.out.println();
            System.out.println();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }


        // 4.3 两个任务任意一个运行完毕,运行 fn,依赖任务的返回结果,有返回值
        firstFuture = getOneCompletableFuture("firstFuture",2);
        CompletableFuture<String> applyToEitherFuture = CompletableFuture
                .supplyAsync(getOneSupplier("applyToEitherAsync()"), executor)
                .applyToEitherAsync(firstFuture, getOneFunction("applyToEitherAsync()"), executor);

        // 等待 future 执行完毕
        runAfterEitherFuture.join();
        acceptEitherFuture.join();
        String applyToEitherFutureRes = applyToEitherFuture.join();
        System.out.println("applyToEitherFutureRes: " + applyToEitherFutureRes);

    }

    /**
     * 五、 处理任务结果或者异常
     * <p> 5.1 exceptionally 处理异常
     * <pre>{@code
     *   public CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn)
     * }
     * </pre>
     *
     * <p> 5.2 handle 任务完成或者异常时运行fn，返回值为fn的返回值
     * <pre>{@code
     *   public <U> CompletableFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn)
     *   public <U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn)
     *   public <U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn,Executor executor)
     * }
     * </pre>
     *
     * <p> 5.3 whenComplete 任务完成或者异常时运行action,无返回值
     * <p> 备注: 该方法相当于一个监听器,即使异常在此处被捕获,也会抛向下一阶段
     * <pre>{@code
     *   public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
     *   public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)
     *   public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action,Executor executor)
     * }
     * </pre>
     */
    public void testFutureResultHandle() {

        // 5.1 exceptionally 处理异常
        CompletableFuture<Integer> exceptionallyFuture = CompletableFuture
                .supplyAsync(() -> 0)
                .thenApplyAsync((data) -> 10 / data)
                .thenApplyAsync((data) -> 1)
                .exceptionally(e -> {
                    System.out.println("exceptionally 中捕获了异常: " + e.getMessage());
                    return -1;
                });

        // 5.2 handle 任务完成或者异常时运行fn，返回值为fn的返回值
        CompletableFuture<Integer> handleAsyncFuture = CompletableFuture
                .supplyAsync(() -> 0)
                .thenApplyAsync((data) -> 10 / data)
                .thenApplyAsync((data) -> 1)
                .handleAsync((data, e) -> {
                    if(e != null) {
                        System.out.println("handleAsync 中捕获了异常: " + e.getMessage());
                    }
                    System.out.println("handleAsync 中获取上一个任务的执行结果: " + data);
                    return data;
                });

        // 5.3 whenComplete 任务完成或者异常时运行action,无返回值
        CompletableFuture<Integer> whenCompleteAsyncFuture = CompletableFuture
                .supplyAsync(() -> 0)
                .thenApplyAsync((data) -> 10 / data)
                .thenApplyAsync((data) -> 1)
                .whenCompleteAsync((data, e) -> {
                    if(e != null) {
                        System.out.println("whenCompleteAsync 中捕获了异常" + e.getMessage());
                    }
                    System.out.println("whenCompleteAsync 中获取上一个任务的执行结果: " + data);
                })
                .handleAsync((data, e) -> {
                    e.printStackTrace();
                    return data;
                });

        Integer exceptionalFutureRes = exceptionallyFuture.join();
        Integer handleFutureRes = handleAsyncFuture.join();
        Integer whenCompletableFutureRes = whenCompleteAsyncFuture.join();
        System.out.println("exceptionalFutureRes: " + exceptionalFutureRes);
        System.out.println("handleFutureRes: " + handleFutureRes);
        System.out.println("whenCompletableFutureRes: " + whenCompletableFutureRes);

    }


    /**
     * 六、 多个任务的简单组合
     * <p> 6.1 allOf() 所有任务需要执行完毕才能触发 next Task 的执行
     * <pre>{@code
     *   public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)
     * }
     * </pre>
     *
     * <p> 6.2 anyOf() 任意一个任务执行完毕都会触发 next Task 的执行
     * <pre>{@code
     *   public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs)
     * }
     * </pre>
     */
    public void testMultiFutureCombine() {

        // 多个任务的简单组合 6.1 allOf() 所有任务需要执行完毕才能触发 next Task 的执行
        CompletableFuture<String> AFuture = getOneCompletableFuture("A",1);
        CompletableFuture<String> BFuture = getOneCompletableFuture("B",3);
        CompletableFuture<Void> allOfFuture = CompletableFuture
                .allOf(AFuture, BFuture)
                .thenRun(() -> {
                    String nowTimeStr = TimeUtil.getNowTimeStr();
                    System.out.println(nowTimeStr + " " + Thread.currentThread() + " allOfFuture 执行完毕");
                });

        try {
            TimeUnit.SECONDS.sleep(5);
            System.out.println();
            System.out.println();
            System.out.println();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        // 6.2 anyOf() 任意一个任务执行完毕都会触发 next Task 的执行
        CompletableFuture<String> CFuture = getOneCompletableFuture("C",1);
        CompletableFuture<String> DFuture = getOneCompletableFuture("D",3);
        CompletableFuture<Void> anyOfFuture = CompletableFuture
                .anyOf(CFuture,DFuture)
                .thenRun(() -> {
                    String nowTimeStr = TimeUtil.getNowTimeStr();
                    System.out.println(nowTimeStr + " " + Thread.currentThread() + " anyOfFuture执行完毕");
                });

        allOfFuture.join();
        anyOfFuture.join();

    }

    /**
     * 七、 CompletableFuture 取消 future 执行
     * <pre>{@code
     *   // mayInterruptIfRunning 无影响；如果任务未完成,则返回异常
     *   public boolean cancel(boolean mayInterruptIfRunning)
     *   //任务是否取消
     *   public boolean isCancelled()
     * }
     * </pre>
     */
    public void testFutureCancel() {

        CompletableFuture<String> cancelFuture = getOneCompletableFuture("cancel future", 3);
        cancelFuture = cancelFuture.exceptionally(e -> {
            e.printStackTrace();
            return "-1";
        });
        String nowTimeStr = TimeUtil.getNowTimeStr();
        System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + " 任务取消前: " + cancelFuture.isCancelled());
        cancelFuture.cancel(true);
        System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + " 任务取消后: " + cancelFuture.isCancelled());

        cancelFuture.join();
    }


    /**
     * 八、 任务的获取 和 完成与否判断
     *   <pre>{@code
     *   // 任务是否执行完成
     *   public boolean isDone()
     *   //阻塞等待 获取返回值
     *   public T join()
     *   // 阻塞等待 获取返回值,区别是get需要返回受检异常
     *   public T get()
     *   //等待阻塞一段时间，并获取返回值
     *   public T get(long timeout, TimeUnit unit)
     *   //未完成则返回指定value
     *   public T getNow(T valueIfAbsent)
     *   //未完成，使用value作为任务执行的结果，任务结束。需要future.get获取
     *   public boolean complete(T value)
     *   //未完成，则是异常调用,返回异常结果，任务结束
     *   public boolean completeExceptionally(Throwable ex)
     *   //判断任务是否因发生异常结束的
     *   public boolean isCompletedExceptionally()
     *   //强制地将返回值设置为value，无论该之前任务是否完成；类似complete
     *   public void obtrudeValue(T value)
     *   //强制地让异常抛出，异常返回，无论该之前任务是否完成；类似completeExceptionally
     *   public void obtrudeException(Throwable ex)
     * }
     * </pre>
     */
    public void testGetRes() {

    }

    private Function<String, String> getOneFunction(String methodName) {
        return (data) -> {
            String nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + "开始执行 " + methodName);
            // 模拟任务执行耗时
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + "执行 " + methodName + "完毕");
            return methodName + " 执行结果 [ " + data + " ]";
        };
    }

    private BiFunction<String, String, String> getOneBiFunction(String methodName) {
        return (data1,data2) -> {

            String nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + "开始执行 " + methodName);
            // 模拟任务执行耗时
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + "执行 " + methodName + "完毕");
            return methodName + " 执行结果 [ " + data1 + "," + data2 + " ]";
        };
    }

    private Consumer<String> getOneConsumer(String methodName) {
        return (data) -> {
            String nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + "开始 执行 " + methodName);
            // 模拟任务执行耗时
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + "执行 " + methodName +" 完毕");
            System.out.println(methodName +" 接受的任务的结果: [" + data + " ]");
        };
    }

    private BiConsumer<String, String> getOneBiConsumer(String methodName) {
        return (data1, data2) -> {
            String nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + "开始 执行 " + methodName);
            // 模拟任务执行耗时
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + "执行 " + methodName +" 完毕");
            System.out.println(methodName +" 接受的两个任务的结果: [" + data1 + ", " + data2 + " ]");
        };
    }

    private Supplier<String> getOneSupplier(String methodName) {
        return () -> {
            String nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + " 开始执行 hello " + methodName);
            // 模拟任务执行耗时
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + " 执行 hello " + methodName + " 完毕");
            return "hello " + methodName;
        };
    }
    private Runnable getOneRunnable(String methodName) {
        return () -> {
            String nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + " 开始执行 " + methodName);
            // 模拟任务执行耗时
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            nowTimeStr = TimeUtil.getNowTimeStr();
            System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + " 执行 " + methodName + " 完毕");

        };
    }
    private CompletableFuture<String> getOneCompletableFuture(String tips, int sleepSeconds) {
        return CompletableFuture
                .supplyAsync(() -> {
                    String nowTimeStr = TimeUtil.getNowTimeStr();
                    System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + " 开始执行 " + tips);
                    // 模拟任务执行耗时
                    try {
                        TimeUnit.SECONDS.sleep(sleepSeconds);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    nowTimeStr = TimeUtil.getNowTimeStr();
                    System.out.println(nowTimeStr + " " + Thread.currentThread().getName() + " 执行 " + tips + " 完毕");

                    return tips + " 执行结果";
                }, executor);
    }

    public static void main(String[] args) {
        CompletableFutureTest completableFutureTest = new CompletableFutureTest();
//        completableFutureTest.testCreateCompletableFuture();
//        completableFutureTest.testCompletableFutureSerialExecute();
//        completableFutureTest.testCompletableFutureParallelANDExecute();
//        completableFutureTest.testCompletableFutureParallelORExecute();
//        completableFutureTest.testFutureResultHandle();
//        completableFutureTest.testMultiFutureCombine();
        completableFutureTest.testFutureCancel();
    }

}
